package chat.server;

import java.io.*;
import java.net.*;

import chat.clientToServerMessage.ClientToServerMessage;
import chat.serverToClientMessage.ServerExitMessage;
import chat.serverToClientMessage.ServerToClientMessage;

/**
 * 
 * @author Marius Eichenberg
 * is started by a server and connects the server with a client
 * every client has a own thread
 */
public class ClientThread extends Thread {

  private Socket client;    
  private Server server;    
  private ObjectOutputStream o;   
  private ObjectInputStream i;
  private String username;
  private Room room;
  private int clientID;
  private boolean run = true;
  private boolean sendEnable = false;
  
  /**
   * constructor of a new Thread that communicates with a given client
   * @param server
   * @param client
   */
  ClientThread(Server server, Socket client, int clientID) { 
    this.client = client;
    this.server = server;
    this.clientID = clientID;
    try{
      o = new ObjectOutputStream(client.getOutputStream());     // IO zum Kommunizieren mit dem zum Thread gehoerenden Client
      i = new ObjectInputStream(client.getInputStream());
    }
    catch(IOException e) {System.out.println("Fehler beim Erstellen der Client-Streams");}   
  }

  
  	/**
  	 * run - to listen to Messages of the client
  	 * handle these messages
  	 */
    public void run(){
    	try{
    		while(run == true){
      
    			try{
    				ClientToServerMessage message = (ClientToServerMessage) i.readObject();
    				message.processOnServer(server, this);
    			}
    			catch(Exception e){
    				System.out.print(e);
    			}
    		}
    }finally { 
    	if (client != null) 
    		try { 
    			client.close();
    		} 
    	catch (IOException e) {
    		System.out.println(e);}
    	}
    }
    
    
    /**
     * sends messages to the client
     * @param message
     */
    public synchronized void send(ServerToClientMessage message){
      if(message instanceof ServerExitMessage){
    	  sendEnable = true;
      }
      if(sendEnable){
    	  try {
    		  o.writeObject(message);
    	  } 
    	  catch (IOException e){
    		  System.out.println(e);}
      }
    }

    
    /**
     * Returns current Room of Client
     * @return
     */
	public Room getRoom() {
		return room;
	}

	
	/**
	 * Returns name of Client
	 * @return
	 */
	public String getUsername(){
		  return username;
	  }

	
	public void setRoom(Room room) {
		this.room = room;	
	}
	
	
	public void setUsername(String name) {
	    username = name;
	}
	
	
	public int getClientID() {
		return clientID;
	}
	
	
	/**
	 * returns the boolean-value of run into false
	 * so the thread will be stopped
	 */
	public synchronized void stopRun() {
		try{
			this.wait(10000);
		}catch(Exception e){
			System.out.println(e);
		}
		run = false;
	}


	public synchronized void setSendEnable(boolean b) {
		sendEnable = true;
	}
}
